(function() {

    if (typeof self === 'undefined' || !self.Prism || !self.document) {
        return;
    }
    
    Prism.hooks.add('complete', function (env) {
        if (!env.code) {
            return;
        }
    
        // Works only for <code> wrapped inside <pre> (not inline).
        var pre = env.element.parentNode;
        var clsReg = /\s*\bcommand-line\b\s*/;
        if (
            !pre || !/pre/i.test(pre.nodeName) ||
                // Abort only if neither the <pre> nor the <code> have the class
            (!clsReg.test(pre.className) && !clsReg.test(env.element.className))
        ) {
            return;
        }
    
        if (env.element.querySelector('.command-line-prompt')) {
            // Abort if prompt already exists.
            return;
        }
    
        if (clsReg.test(env.element.className)) {
            // Remove the class "command-line" from the <code>
            env.element.className = env.element.className.replace(clsReg, '');
        }
        if (!clsReg.test(pre.className)) {
            // Add the class "command-line" to the <pre>
            pre.className += ' command-line';
        }
    
        var getAttribute = function(key, defaultValue) {
            return (pre.getAttribute(key) || defaultValue).replace(/"/g, '&quot');
        };
    
        // Create the "rows" that will become the command-line prompts. -- cwells
        var lines = new Array(1 + env.code.split('\n').length);
        var promptText = getAttribute('data-prompt', '');
        if (promptText !== '') {
            lines = lines.join('<span data-prompt="' + promptText + '"></span>');
        } else {
            var user = getAttribute('data-user', 'user');
            var host = getAttribute('data-host', 'localhost');
            lines = lines.join('<span data-user="' + user + '" data-host="' + host + '"></span>');
        }
    
        // Create the wrapper element. -- cwells
        var prompt = document.createElement('span');
        prompt.className = 'command-line-prompt';
        prompt.innerHTML = lines;
    
        // Mark the output lines so they can be styled differently (no prompt). -- cwells
        var outputSections = pre.getAttribute('data-output') || '';
        outputSections = outputSections.split(',');
        for (var i = 0; i < outputSections.length; i++) {
            var outputRange = outputSections[i].split('-');
            var outputStart = parseInt(outputRange[0]);
            var outputEnd = outputStart; // Default: end at the first line when it's not an actual range. -- cwells
            if (outputRange.length === 2) {
                outputEnd = parseInt(outputRange[1]);
            }
    
            if (!isNaN(outputStart) && !isNaN(outputEnd)) {
                for (var j = outputStart; j <= outputEnd && j <= prompt.children.length; j++) {
                    var node = prompt.children[j - 1];
                    node.removeAttribute('data-user');
                    node.removeAttribute('data-host');
                    node.removeAttribute('data-prompt');
                }
            }
        }
    
        env.element.innerHTML = prompt.outerHTML + env.element.innerHTML;
    });
    
    }());